using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Concurrent;
using NLog;
using LDNS.Models;

namespace LDNS.Utilities
{
    /// <summary>
    /// 上游DNS服务器管理器
    /// 负责管理上游DNS服务器的连接、查询和缓存索引
    /// 作者：huobing
    /// </summary>
    public class UpstreamDnsManager : IDisposable
    {
        #region 字段和属性

        // 上游DNS服务器列表
        private readonly List<string> _upstreamDnsServers = [];
        
        // 索引：按上游DNS服务器IP记录域名集合，用于网络变化时精准清理缓存
        private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, byte>> _upstreamCacheIndex = new();
        
        private readonly object _upstreamLock = new();
        private string? _lastUsedUpstreamServer;
        
        // 上游DNS主域名映射（持久化于 Conf/upstream_domains.conf）
        private readonly ConcurrentDictionary<string, string> _upstreamMainDomains = new(StringComparer.OrdinalIgnoreCase);
        
        // 日志记录器
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        
        /// <summary>
        /// 获取上游DNS服务器列表
        /// </summary>
        public List<string> UpstreamServers => [.. _upstreamDnsServers];

        // 单例实例字段
        private static UpstreamDnsManager? _instance;
        private static readonly object _instanceLock = new();
        private static List<string>? _instanceParameters;

        /// <summary>
        /// 获取单例实例（带参数）
        /// </summary>
        /// <param name="upstreamDnsServers">上游DNS服务器列表</param>
        /// <returns>UpstreamDnsManager单例实例</returns>
        public static UpstreamDnsManager GetInstance(List<string>? upstreamDnsServers)
        {
            lock (_instanceLock)
            {
                // 如果实例不存在，或者参数发生变化，则重新创建实例
                bool shouldRecreate = false;
                if (_instance == null || _instanceParameters == null)
                {
                    shouldRecreate = true;
                }
                else if (upstreamDnsServers == null)
                {
                    // 如果新参数为null，只有当当前参数不为空时才重新创建
                    shouldRecreate = _instanceParameters.Count > 0;
                }
                else
                {
                    // 只有当参数不相等时才重新创建
                    shouldRecreate = !_instanceParameters.SequenceEqual(upstreamDnsServers);
                }
                
                if (shouldRecreate)
                {
                    _instance?.Dispose();
                    _instance = new UpstreamDnsManager(upstreamDnsServers);
                    _instanceParameters = upstreamDnsServers != null ? new List<string>(upstreamDnsServers) : [];
                }
                return _instance ?? throw new InvalidOperationException("UpstreamDnsManager实例未初始化");
            }
        }

        /// <summary>
        /// 获取当前单例实例（如果已创建）
        /// </summary>
        public static UpstreamDnsManager Instance
        {
            get
            {
                lock (_instanceLock)
                {
                    return _instance ?? throw new InvalidOperationException("UpstreamDnsManager实例未初始化");
                }
            }
        }

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public UpstreamDnsManager()
        {
            // 加载上游主域名映射
            try
            {
                var map = UpstreamDomainManager.Instance.GetDomainMap();
                foreach (var kv in map)
                {
                    _upstreamMainDomains[kv.Key] = kv.Value;
                }
                _logger.Info($"已加载上游主域名配置 {map.Count} 项");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"加载上游主域名配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="upstreamDnsServers">上游DNS服务器列表</param>
        public UpstreamDnsManager(IEnumerable<string>? upstreamDnsServers)
            : this()
        {
            if (upstreamDnsServers != null)
            {
                // 过滤掉127.0.0.1作为上游DNS服务器
                _upstreamDnsServers.AddRange(upstreamDnsServers.Where(server => !string.Equals(server.Trim(), "127.0.0.1", StringComparison.OrdinalIgnoreCase)));
            }

            // 如果没有指定上游DNS服务器，添加默认值
            if (_upstreamDnsServers.Count == 0)
            {
                _upstreamDnsServers.Add("8.8.8.8");
                _upstreamDnsServers.Add("114.114.114.114");
            }
        }
        #endregion

        #region 上游DNS管理方法

        /// <summary>
        /// 更新上游DNS优先级（将指定列表置于首位，保留原有其他并去重）
        /// </summary>
        public void UpdatePreferredUpstreamDnsServers(IEnumerable<string>? preferred)
        {
            if (preferred == null) return;
            // 过滤掉127.0.0.1作为上游DNS服务器
            var pref = preferred.Where(s => !string.IsNullOrWhiteSpace(s) && !string.Equals(s.Trim(), "127.0.0.1", StringComparison.OrdinalIgnoreCase)).Distinct().ToList();
            lock (_upstreamLock)
            {
                var rest = _upstreamDnsServers.Where(s => !pref.Contains(s) && !string.Equals(s.Trim(), "127.0.0.1", StringComparison.OrdinalIgnoreCase)).ToList();
                _upstreamDnsServers.Clear();
                _upstreamDnsServers.AddRange(pref);
                _upstreamDnsServers.AddRange(rest);
            }
            _logger.Debug($"更新上游DNS优先级: {string.Join(", ", _upstreamDnsServers)}");
        }

        /// <summary>
        /// 根据上游DNS服务器IP清除缓存（清除由这些上游DNS产生的域名缓存）
        /// 注：此方法供外部调用，但实际缓存清理需要通过LocalDNSService的接口完成
        /// </summary>
        /// <param name="dnsServers">DNS服务器列表</param>
        public void ClearCacheByUpstreamDnsServers(IEnumerable<string>? dnsServers)
        {
            if (dnsServers == null) return;
            foreach (var dns in dnsServers)
            {
                if (_upstreamCacheIndex.TryRemove(dns, out var domains))
                {
                    _logger.Info($"已清除来自上游DNS {dns} 的缓存索引 {domains.Count} 项");
                }
            }
        }
        
        /// <summary>
        /// 根据上游DNS服务器IP清除缓存（清除由这些上游DNS产生的域名缓存）
        /// </summary>
        /// <param name="dnsServers">DNS服务器列表</param>
        /// <param name="cache">DNS缓存字典</param>
        public void ClearCacheByUpstreamDnsServers(IEnumerable<string>? dnsServers, ConcurrentDictionary<string, DnsCacheItem> cache)
        {
            if (dnsServers == null) return;
            foreach (var dns in dnsServers)
            {
                if (_upstreamCacheIndex.TryRemove(dns, out var domains))
                {
                    foreach (var kv in domains.Keys)
                    {
                        cache.TryRemove(kv, out _);
                    }
                    _logger.Info($"已清除来自上游DNS {dns} 的缓存 {domains.Count} 项");
                }
            }
        }

        /// <summary>
        /// 获取上游DNS信息（用于展示）
        /// </summary>
        public List<UpstreamDnsInfo> GetUpstreamDnsInfos()
        {
            var list = new List<UpstreamDnsInfo>();
            lock (_upstreamLock)
            {
                foreach (var ip in _upstreamDnsServers)
                {
                    int count = 0;
                    if (_upstreamCacheIndex.TryGetValue(ip, out var domains))
                    {
                        count = domains.Count;
                    }
                    _upstreamMainDomains.TryGetValue(ip, out var mainDomain);
                    list.Add(new UpstreamDnsInfo
                    {
                        Ip = ip,
                        CacheCount = count,
                        MainDomain = string.IsNullOrWhiteSpace(mainDomain) ? string.Empty : mainDomain
                    });
                }
            }
            return list;
        }

        /// <summary>
        /// 添加上游DNS服务器到缓存索引
        /// </summary>
        /// <param name="dnsServer">DNS服务器IP</param>
        /// <param name="domain">域名</param>
        public void AddToCacheIndex(string dnsServer, string domain)
        {
            if (!string.IsNullOrWhiteSpace(dnsServer) && !string.IsNullOrWhiteSpace(domain))
            {
                var index = _upstreamCacheIndex.GetOrAdd(dnsServer, _ => new ConcurrentDictionary<string, byte>());
                index[domain.ToLower()] = 0;
            }
        }

        #endregion

        #region DNS查询方法

        /// <summary>
        /// 向上游DNS服务器查询并获取所有IP地址
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>解析的IP地址列表</returns>
        public async Task<List<string>> QueryUpstreamDnsAllAsync(string domain)
        {
            var allIpAddresses = new List<string>();
            var ipSet = new HashSet<string>(); // 用于去重
            
            return await QueryUpstreamDnsAllAsync(domain, ipSet);
        }
        
        /// <summary>
        /// 向上游DNS服务器查询并获取所有IP地址（内部方法，用于递归查询）
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="ipSet">用于去重的IP集合</param>
        /// <returns>解析的IP地址列表</returns>
        private async Task<List<string>> QueryUpstreamDnsAllAsync(string domain, HashSet<string> ipSet)
        {
            var allIpAddresses = new List<string>();
            var processedCnames = new HashSet<string>(); // 用于避免重复处理CNAME记录
            var processedDomains = new HashSet<string>(); // 用于避免重复处理域名
            
            foreach (var dnsServer in _upstreamDnsServers)
            {
                try
                {
                    // 构建候选查询域名列表：原始域名、主域名、父域名+主域名
                    var candidates = new List<string>();
                    candidates.Add(domain);
                    if (_upstreamMainDomains.TryGetValue(dnsServer, out var baseDomain) && !string.IsNullOrWhiteSpace(baseDomain))
                    {
                        candidates.Add(baseDomain);
                        // 对原始域名的父域名逐级组合为 suffix.baseDomain
                        var parts = domain.Split('.', StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 1; i < parts.Length; i++)
                        {
                            var suffix = string.Join('.', parts.Skip(i));
                            var combined = string.IsNullOrWhiteSpace(suffix) ? baseDomain : $"{suffix}.{baseDomain}";
                            if (!candidates.Contains(combined, StringComparer.OrdinalIgnoreCase))
                                candidates.Add(combined);
                        }
                    }
                    
                    using var dnsClient = new UdpClient(AddressFamily.InterNetwork);
                    var dnsEndPoint = new IPEndPoint(IPAddress.Parse(dnsServer), 53);
                    
                    foreach (var cand in candidates)
                    {
                        // 跳过已经处理过的域名
                        if (!processedDomains.Add(cand))
                        {
                            continue;
                        }
                        
                        var queryData = CreateDnsQuery(cand);
                        await dnsClient.SendAsync(queryData, queryData.Length, dnsEndPoint);
                        var receiveTask = dnsClient.ReceiveAsync();
                        var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
                        var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
                        if (completedTask == receiveTask)
                        {
                            var response = receiveTask.Result;
                            var ipAddresses = ExtractAllIpFromDnsResponse(response.Buffer);
                            
                            // 添加新IP到集合中（去重）
                            foreach (var ip in ipAddresses)
                            {
                                if (ipSet.Add(ip))
                                {
                                    allIpAddresses.Add(ip);
                                }
                            }
                            
                            // 如果没有找到A记录，尝试检查是否有CNAME记录
                            var cnameDomain = ExtractCnameFromDnsResponse(response.Buffer);
                            if (!string.IsNullOrWhiteSpace(cnameDomain) && 
                                !cnameDomain.Equals(domain, StringComparison.OrdinalIgnoreCase) &&
                                processedCnames.Add(cnameDomain))
                            {
                                _logger.Info($"检测到CNAME记录: {domain} -> {cnameDomain}，进行递归查询");
                                // 递归查询CNAME指向的域名
                                var cnameIps = await QueryUpstreamDnsAllAsync(cnameDomain, ipSet);
                                // 注意：不添加返回结果，因为已经在递归调用中处理了
                            }
                        }
                        else
                        {
                            _logger.Error($"向上游DNS服务器 {dnsServer} 查询 {cand} 超时");
                        }
                    }
                    
                    // 如果从当前DNS服务器获取到了IP，记录最后使用的服务器
                    if (allIpAddresses.Count > 0)
                    {
                        _lastUsedUpstreamServer = dnsServer;
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"向上游DNS服务器 {dnsServer} 查询 {domain} 失败: {ex.Message}");
                }
            }
            
            return allIpAddresses;
        }
        
        /// <summary>
        /// 向上游DNS服务器查询
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>解析的IP地址</returns>
        public async Task<string?> QueryUpstreamDnsAsync(string domain)
        {
            foreach (var dnsServer in _upstreamDnsServers)
            {
                try
                {
                    // 构建候选查询域名列表：原始域名、主域名、父域名+主域名
                    var candidates = new List<string>();
                    candidates.Add(domain);
                    if (_upstreamMainDomains.TryGetValue(dnsServer, out var baseDomain) && !string.IsNullOrWhiteSpace(baseDomain))
                    {
                        candidates.Add(baseDomain);
                        // 对原始域名的父域名逐级组合为 suffix.baseDomain
                        var parts = domain.Split('.', StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 1; i < parts.Length; i++)
                        {
                            var suffix = string.Join('.', parts.Skip(i));
                            var combined = string.IsNullOrWhiteSpace(suffix) ? baseDomain : $"{suffix}.{baseDomain}";
                            if (!candidates.Contains(combined, StringComparer.OrdinalIgnoreCase))
                                candidates.Add(combined);
                        }
                    }
                    
                    using var dnsClient = new UdpClient(AddressFamily.InterNetwork);
                    var dnsEndPoint = new IPEndPoint(IPAddress.Parse(dnsServer), 53);
                    
                    foreach (var cand in candidates)
                    {
                        var queryData = CreateDnsQuery(cand);
                        await dnsClient.SendAsync(queryData, queryData.Length, dnsEndPoint);
                        var receiveTask = dnsClient.ReceiveAsync();
                        var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
                        var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
                        if (completedTask == receiveTask)
                        {
                            var response = receiveTask.Result;
                            var ipAddress = ExtractIpFromDnsResponse(response.Buffer);
                            
                            if (!string.IsNullOrWhiteSpace(ipAddress))
                            {
                                _lastUsedUpstreamServer = dnsServer;
                                return ipAddress;
                            }
                            
                            // 如果没有找到A记录，尝试检查是否有CNAME记录
                            var cnameDomain = ExtractCnameFromDnsResponse(response.Buffer);
                            if (!string.IsNullOrWhiteSpace(cnameDomain) && !cnameDomain.Equals(domain, StringComparison.OrdinalIgnoreCase))
                            {
                                _logger.Info($"检测到CNAME记录: {domain} -> {cnameDomain}，进行递归查询");
                                // 递归查询CNAME指向的域名
                                var cnameIp = await QueryUpstreamDnsAsync(cnameDomain);
                                if (!string.IsNullOrWhiteSpace(cnameIp))
                                {
                                    _lastUsedUpstreamServer = dnsServer;
                                    return cnameIp;
                                }
                            }
                        }
                        else
                        {
                            _logger.Error($"向上游DNS服务器 {dnsServer} 查询 {cand} 超时");
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"向上游DNS服务器 {dnsServer} 查询 {domain} 失败: {ex.Message}");
                }
            }
            
            return null;
        }

        /// <summary>
        /// 向上游DNS服务器查询反向解析
        /// </summary>
        /// <param name="reverseDomain">反向域名</param>
        /// <returns>主机名</returns>
        public async Task<string?> QueryUpstreamDnsForReverseLookupAsync(string reverseDomain)
        {
            foreach (var dnsServer in _upstreamDnsServers)
            {
                try
                {
                    // 使用指定的DNS服务器进行查询
                    using var dnsClient = new UdpClient(AddressFamily.InterNetwork);
                    
                    // 创建DNS查询数据包（PTR记录查询）
                    var queryData = CreatePTRRecordQuery(reverseDomain);
                    
                    // 发送查询到指定的DNS服务器
                    var dnsEndPoint = new IPEndPoint(IPAddress.Parse(dnsServer), 53);
                    await dnsClient.SendAsync(queryData, queryData.Length, dnsEndPoint);
                    
                    // 接收响应（设置超时）
                    var receiveTask = dnsClient.ReceiveAsync();
                    var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
                    
                    var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
                    
                    if (completedTask == receiveTask)
                    {
                        var response = receiveTask.Result;
                        var hostname = ExtractHostnameFromDnsResponse(response.Buffer);
                        
                        if (!string.IsNullOrWhiteSpace(hostname))
                        {
                            return hostname;
                        }
                    }
                    else
                    {
                        _logger.Error($"向上游DNS服务器 {dnsServer} 查询反向解析 {reverseDomain} 超时");
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, $"向上游DNS服务器 {dnsServer} 查询反向解析 {reverseDomain} 失败: {ex.Message}");
                }
            }
            
            return null;
        }

        #endregion

        #region DNS数据包处理方法

        /// <summary>
        /// 创建DNS查询数据包
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>DNS查询数据</returns>
        private static byte[] CreateDnsQuery(string domain)
        {
            var query = new List<byte>();
            
            // 事务ID (随机)
            var random = new Random();
            query.Add((byte)random.Next(0, 256));
            query.Add((byte)random.Next(0, 256));
            
            // 标志：标准查询，递归查询
            query.Add(0x01); // QR=0, OPCODE=0, AA=0, TC=0, RD=1
            query.Add(0x00); // RA=0, Z=0, RCODE=0
            
            // 问题数量 = 1
            query.Add(0x00);
            query.Add(0x01);
            
            // 回答数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 权威记录数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 附加记录数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 域名部分
            var domainParts = domain.Split('.');
            foreach (var part in domainParts)
            {
                query.Add((byte)part.Length);
                query.AddRange(Encoding.UTF8.GetBytes(part));
            }
            query.Add(0x00); // 域名结束
            
            // 查询类型 A记录 = 1
            query.Add(0x00);
            query.Add(0x01);
            
            // 查询类 IN = 1
            query.Add(0x00);
            query.Add(0x01);
            
            return [.. query];
        }

        /// <summary>
        /// 创建PTR记录查询数据包
        /// </summary>
        /// <param name="reverseDomain">反向域名</param>
        /// <returns>DNS查询数据</returns>
        private static byte[] CreatePTRRecordQuery(string reverseDomain)
        {
            var query = new List<byte>();
            
            // 事务ID (随机)
            var random = new Random();
            query.Add((byte)random.Next(0, 256));
            query.Add((byte)random.Next(0, 256));
            
            // 标志：标准查询，递归查询
            query.Add(0x01); // QR=0, OPCODE=0, AA=0, TC=0, RD=1
            query.Add(0x00); // RA=0, Z=0, RCODE=0
            
            // 问题数量 = 1
            query.Add(0x00);
            query.Add(0x01);
            
            // 回答数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 权威记录数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 附加记录数量 = 0
            query.Add(0x00);
            query.Add(0x00);
            
            // 域名部分
            var domainParts = reverseDomain.Split('.');
            foreach (var part in domainParts)
            {
                query.Add((byte)part.Length);
                query.AddRange(Encoding.UTF8.GetBytes(part));
            }
            query.Add(0x00); // 域名结束
            
            // 查询类型 PTR记录 = 12
            query.Add(0x00);
            query.Add(0x0C);
            
            // 查询类 IN = 1
            query.Add(0x00);
            query.Add(0x01);
            
            return [.. query];
        }

        /// <summary>
        /// 从DNS响应中提取CNAME记录
        /// </summary>
        /// <param name="responseBuffer">DNS响应缓冲区</param>
        /// <returns>CNAME域名</returns>
        private string? ExtractCnameFromDnsResponse(byte[] responseBuffer)
        {
            try
            {
                if (responseBuffer.Length < 12) return null;
                
                // 跳过DNS头部(12字节)
                int offset = 12;
                
                // 跳过问题部分
                var qdcount = (responseBuffer[4] << 8) | responseBuffer[5];
                for (int i = 0; i < qdcount; i++)
                {
                    // 跳过查询名称
                    while (offset < responseBuffer.Length && responseBuffer[offset] != 0)
                    {
                        int len = responseBuffer[offset];
                        if (len > 63) // 压缩指针
                        {
                            offset += 2;
                            break;
                        }
                        offset += len + 1;
                        if (offset >= responseBuffer.Length) break;
                    }
                    if (offset < responseBuffer.Length) offset++; // 跳过结束的0
                    
                    // 跳过查询类型和查询类
                    offset += 4;
                }
                
                // 读取回答数量
                var ancount = (responseBuffer[6] << 8) | responseBuffer[7];
                
                // 解析回答部分
                for (int i = 0; i < ancount; i++)
                {
                    // 跳过名称部分
                    if (offset < responseBuffer.Length && responseBuffer[offset] > 63)
                    {
                        offset += 2; // 压缩指针
                    }
                    else
                    {
                        while (offset < responseBuffer.Length && responseBuffer[offset] != 0)
                        {
                            offset++;
                        }
                        offset++; // 跳过结束的0
                    }
                    
                    if (offset + 10 > responseBuffer.Length) break;
                    
                    // 读取类型
                    var type = (responseBuffer[offset] << 8) | responseBuffer[offset + 1];
                    offset += 8; // 跳过类型、类、TTL
                    
                    // 读取数据长度
                    var rdlength = (responseBuffer[offset] << 8) | responseBuffer[offset + 1];
                    offset += 2;
                    
                    if (offset + rdlength > responseBuffer.Length) break;
                    
                    // 如果是CNAME记录(类型5)
                    if (type == 5)
                    {
                        var cname = ExtractDomainNameFromDnsBuffer(responseBuffer, offset);
                        if (!string.IsNullOrWhiteSpace(cname))
                        {
                            _logger.Debug($"从DNS响应中提取到CNAME记录: {cname}");
                            return cname;
                        }
                    }
                    
                    offset += rdlength;
                }
                
                return null;
            }
            catch (Exception ex)
            {
                _logger.Error($"从DNS响应中提取CNAME记录失败: {ex.Message}");
                return null;
            }
        }
        
        /// <summary>
        /// 从DNS缓冲区中提取域名
        /// </summary>
        /// <param name="buffer">DNS缓冲区</param>
        /// <param name="offset">起始偏移量</param>
        /// <returns>域名</returns>
        private string ExtractDomainNameFromDnsBuffer(byte[] buffer, int offset)
        {
            try
            {
                var domain = "";
                var originalOffset = offset;
                var jumped = false;
                
                while (offset < buffer.Length)
                {
                    byte len = buffer[offset];
                    
                    if (len == 0) // 结束标记
                    {
                        if (!jumped) offset++;
                        break;
                    }
                    
                    // 检查是否是压缩指针(前两位为11)
                    if ((len & 0xC0) == 0xC0)
                    {
                        if (offset + 1 >= buffer.Length) break;
                        
                        // 获取指针位置
                        var pointer = ((len & 0x3F) << 8) | buffer[offset + 1];
                        
                        // 如果是第一次跳转，记录当前位置并继续
                        if (!jumped)
                        {
                            offset += 2;
                            jumped = true;
                        }
                        
                        // 跳转到指针位置
                        offset = pointer;
                        continue;
                    }
                    
                    // 普通标签长度
                    offset++;
                    if (offset + len > buffer.Length) break;
                    
                    if (domain.Length > 0) domain += ".";
                    domain += System.Text.Encoding.ASCII.GetString(buffer, offset, len);
                    
                    offset += len;
                }
                
                return domain.ToLowerInvariant();
            }
            catch (Exception ex)
            {
                _logger.Error($"从DNS缓冲区中提取域名失败: {ex.Message}");
                return "";
            }
        }
        
        /// <summary>
        /// 从DNS响应中提取所有IP地址
        /// </summary>
        /// <param name="responseData">响应数据</param>
        /// <returns>IP地址列表</returns>
        private List<string> ExtractAllIpFromDnsResponse(byte[] responseData)
        {
            try
            {
                var ipAddresses = new List<string>();
                var ipSet = new HashSet<string>(); // 用于去重的HashSet
                
                // 增强边界检查
                if (responseData == null || responseData.Length < 12) return ipAddresses;
                
                // 检查响应码
                var rcode = responseData[3] & 0x0F;
                if (rcode != 0) return ipAddresses; // 非零表示错误
                
                // 获取回答数量（添加边界检查）
                if (responseData.Length < 8) return ipAddresses;
                var answerCount = (responseData[6] << 8) | responseData[7];
                if (answerCount == 0) return ipAddresses;
                
                // 跳过问题部分
                int position = 12;
                while (position < responseData.Length && responseData[position] != 0)
                {
                    // 添加边界检查，防止长度字节本身越界
                    if (position >= responseData.Length) break;
                    
                    int length = responseData[position];
                    // 添加额外检查，确保不会跳过太多字节
                    if (length > responseData.Length - position - 1) break;
                    
                    position += length + 1;
                }
                
                // 添加边界检查，确保可以跳过QType和QClass
                if (position + 5 > responseData.Length) return ipAddresses;
                position += 5; // 跳过结束的0和QType、QClass
                
                // 查找A记录或CNAME记录
                for (int i = 0; i < answerCount; i++)
                {
                    // 确保有足够的字节可读
                    if (position >= responseData.Length) break;
                    
                    // 跳过域名指针（2字节）
                    if (responseData[position] == 0xC0)
                    {
                        if (position + 1 >= responseData.Length) break;
                        position += 2;
                    }
                    else
                    {
                        // 跳过域名
                        while (position < responseData.Length && responseData[position] != 0)
                        {
                            // 添加边界检查
                            if (position >= responseData.Length) break;
                            
                            int length = responseData[position];
                            // 添加额外检查，防止长度字节本身越界
                            if (length > responseData.Length - position - 1) break;
                            
                            position += length + 1;
                        }
                        // 跳过结束的0
                        if (position < responseData.Length) position++;
                    }
                    
                    // 检查记录类型（添加边界检查）
                    if (position + 1 >= responseData.Length) break;
                    var type = (responseData[position] << 8) | responseData[position + 1];
                    position += 2;
                    
                    // 跳过类（添加边界检查）
                    if (position + 1 >= responseData.Length) break;
                    position += 2;
                    
                    // 跳过TTL（添加边界检查）
                    if (position + 3 >= responseData.Length) break;
                    position += 4;
                    
                    // 获取数据长度（添加边界检查）
                    if (position + 1 >= responseData.Length) break;
                    var dataLength = (responseData[position] << 8) | responseData[position + 1];
                    position += 2;
                    
                    // 检查是否为A记录且有足够的数据长度
                    if (type == 1 && dataLength == 4)
                    {
                        // 添加边界检查，确保有足够的数据来构建IP地址
                        if (position + 3 < responseData.Length)
                        {
                            var ipAddress = $"{responseData[position]}.{responseData[position + 1]}.{responseData[position + 2]}.{responseData[position + 3]}";
                            // 使用HashSet进行去重
                            if (ipSet.Add(ipAddress))
                            {
                                ipAddresses.Add(ipAddress);
                            }
                        }
                    }
                    // 处理CNAME记录（类型5）
                    else if (type == 5)
                    {
                        // CNAME记录包含一个域名，我们暂时跳过它，继续查找A记录
                        // 在实际应用中，可能需要递归查询CNAME指向的域名
                        _logger.Debug($"遇到CNAME记录，跳过并继续查找A记录");
                    }
                    
                    // 跳过其他类型的数据（添加边界检查）
                    if (position + dataLength <= responseData.Length)
                    {
                        position += dataLength;
                    }
                    else
                    {
                        // 如果数据长度超出范围，跳出循环
                        break;
                    }
                }
                
                return ipAddresses;
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"从DNS响应提取IP失败: {ex.Message}");
                return new List<string>();
            }
        }

        /// <summary>
        /// 从DNS响应中提取IP地址（兼容性方法）
        /// </summary>
        /// <param name="responseData">响应数据</param>
        /// <returns>IP地址</returns>
        private string? ExtractIpFromDnsResponse(byte[] responseData)
        {
            var ipAddresses = ExtractAllIpFromDnsResponse(responseData);
            return ipAddresses.Count > 0 ? ipAddresses[0] : null;
        }
        
        /// <summary>
        /// 从DNS响应中提取主机名（PTR记录）
        /// </summary>
        /// <param name="responseData">响应数据</param>
        /// <returns>主机名</returns>
        private string? ExtractHostnameFromDnsResponse(byte[] responseData)
        {
            try
            {
                if (responseData.Length < 12) return null;
                
                // 检查响应码
                var rcode = responseData[3] & 0x0F;
                if (rcode != 0) return null; // 非零表示错误
                
                // 获取回答数量
                var answerCount = (responseData[6] << 8) | responseData[7];
                if (answerCount == 0) return null;
                
                // 跳过问题部分
                int position = 12;
                while (position < responseData.Length && responseData[position] != 0)
                {
                    int length = responseData[position];
                    position += length + 1;
                }
                position += 5; // 跳过结束的0和QType、QClass
                
                // 查找PTR记录
                for (int i = 0; i < answerCount && position < responseData.Length - 10; i++)
                {
                    // 跳过域名指针（2字节）
                    if (responseData[position] == 0xC0)
                    {
                        position += 2;
                    }
                    else
                    {
                        // 跳过域名
                        while (position < responseData.Length && responseData[position] != 0)
                        {
                            int length = responseData[position];
                            position += length + 1;
                        }
                        position++; // 跳过结束的0
                    }
                    
                    // 检查记录类型
                    var type = (responseData[position] << 8) | responseData[position + 1];
                    position += 2;
                    
                    // 跳过类
                    position += 2;
                    
                    // 跳过TTL
                    position += 4;
                    
                    // 获取数据长度
                    var dataLength = (responseData[position] << 8) | responseData[position + 1];
                    position += 2;
                    
                    if (type == 12) // PTR记录
                    {
                        // 提取主机名
                        var hostnameBuilder = new StringBuilder();
                        int endPosition = position + dataLength;
                        
                        while (position < endPosition && position < responseData.Length)
                        {
                            if (responseData[position] == 0xC0) // 指针
                            {
                                int pointerPosition = responseData[position + 1];
                                var pointerHostname = ExtractDomainFromPointer(responseData, pointerPosition);
                                hostnameBuilder.Append(pointerHostname);
                                position += 2;
                                break;
                            }
                            else if (responseData[position] > 0) // 标签
                            {
                                int labelLength = responseData[position];
                                position++;
                                
                                if (position + labelLength <= responseData.Length)
                                {
                                    var label = Encoding.UTF8.GetString(responseData, position, labelLength);
                                    hostnameBuilder.Append(label);
                                    position += labelLength;
                                    
                                    if (position < endPosition && position < responseData.Length && responseData[position] != 0)
                                    {
                                        hostnameBuilder.Append(".");
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else // 结束符
                            {
                                position++;
                                break;
                            }
                        }
                        
                        var hostname = hostnameBuilder.ToString();
                        if (!string.IsNullOrEmpty(hostname))
                        {
                            return hostname;
                        }
                    }
                    
                    position += dataLength;
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"从DNS响应提取主机名失败: {ex.Message}");
            }
            
            return null;
        }

        /// <summary>
        /// 从指针中提取域名
        /// </summary>
        /// <param name="responseData">响应数据</param>
        /// <param name="pointerPosition">指针位置</param>
        /// <returns>域名</returns>
        private static string ExtractDomainFromPointer(byte[] responseData, int pointerPosition)
        {
            var domainBuilder = new StringBuilder();
            int position = pointerPosition;
            
            while (position < responseData.Length && responseData[position] != 0)
            {
                if (responseData[position] == 0xC0) // 嵌套指针
                {
                    int nestedPosition = responseData[position + 1];
                    var nestedDomain = ExtractDomainFromPointer(responseData, nestedPosition);
                    domainBuilder.Append(nestedDomain);
                    position += 2;
                    break;
                }
                else if (responseData[position] > 0) // 标签
                {
                    int labelLength = responseData[position];
                    position++;
                    
                    if (position + labelLength <= responseData.Length)
                    {
                        var label = Encoding.UTF8.GetString(responseData, position, labelLength);
                        domainBuilder.Append(label);
                        position += labelLength;
                        
                        if (position < responseData.Length && responseData[position] != 0)
                        {
                            domainBuilder.Append(".");
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else // 结束符
                {
                    position++;
                    break;
                }
            }
            
            return domainBuilder.ToString();
        }

        /// <summary>
        /// 记录域名映射关系（根据上次使用的DNS服务器）
        /// </summary>
        /// <param name="domain">域名</param>
        public void RecordDomainMapping(string domain)
        {
            if (!string.IsNullOrWhiteSpace(_lastUsedUpstreamServer))
            {
                AddToCacheIndex(_lastUsedUpstreamServer, domain);
            }
        }
        
        /// <summary>
        /// 设置上游DNS服务器的主域名
        /// </summary>
        /// <param name="dnsServerIp">DNS服务器IP</param>
        /// <param name="mainDomain">主域名</param>
        public void SetUpstreamMainDomain(string dnsServerIp, string mainDomain)
        {
            if (string.IsNullOrWhiteSpace(dnsServerIp))
                throw new ArgumentNullException(nameof(dnsServerIp));
                
            // 更新内存中的映射
            _upstreamMainDomains[dnsServerIp] = mainDomain;
            
            // 持久化到配置文件
            try
            {
                UpstreamDomainManager.Instance.AddDomainMapping(dnsServerIp, mainDomain);
                _logger.Info($"已保存上游DNS {dnsServerIp} 的主域名: {mainDomain}");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"保存上游主域名配置失败: {ex.Message}");
                throw;
            }
        }
        
        /// <summary>
        /// 向上游DNS服务器查询（兼容接口）
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>解析的IP地址</returns>
        public async Task<string?> QueryDnsAsync(string domain)
        {
            return await QueryUpstreamDnsAsync(domain);
        }
        
        /// <summary>
        /// 向上游DNS服务器查询反向解析（兼容接口）
        /// </summary>
        /// <param name="reverseDomain">反向域名</param>
        /// <returns>主机名</returns>
        public async Task<string?> QueryReverseDnsAsync(string reverseDomain)
        {
            return await QueryUpstreamDnsForReverseLookupAsync(reverseDomain);
        }
        
        #endregion

        #region IDisposable实现

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            // 清理资源
            _upstreamCacheIndex.Clear();
            _upstreamMainDomains.Clear();
        }

        #endregion
    }
}